package compilador;

import compilador.analisadorLexico.Token;
import compilador.analisadorLexico.TokenErro;
import compilador.analisadorSemantico.ErroSemantico;
import compilador.analisadorSintatico.simboloGramatical.ErroSintatico;
import java.util.List;

/**
 *  Classe que estabelece a conexão entre a
 *  interface fráfica e o Analisador Lexico
 * 
 * @author Joao Luiz
 */
public class comunicador {
    
    private Compilador compilador;

    /**
     * Construtor que recebe o codigo-fonte
     * do programa a ser Analisado Lexicamente
     * 
     * @param codigo
     */
    public comunicador(String codigo) {
        compilador = new Compilador();
        
        compilador.compilar(codigo);
    }

    /**
     * Metodo que coleta os tokens gerados pelo
     * Analisador Lexico do codigo-fonte.
     * 
     * @return uma String com todos os tokens
     */
    public String getTokens() {
       StringBuilder tokensStBuilder = new StringBuilder();
       
       List<Token> tokens = compilador.getTokens();
       
       if(tokens == null || tokens.isEmpty()){
           tokensStBuilder.append("Não há tokens!");
       
       } else {
           for(Token t : tokens) {
               tokensStBuilder.append("<"+t.getTokenClass().toString()+", '"
                                        +t.getAtributo()+"'> (linha "+t.getLinha()+")\n");
           }
       }
       
       return tokensStBuilder.toString();
    }
    
    /**
     * Metodo que coleta os erros lexicos
     * gerados pelo Analisador Lexico
     * 
     * @return uma String com todos os erros lexicos
     */
    public String getErros() {
        
        StringBuilder errosStBuilder = new StringBuilder();
        
        //Erros Léxicos
        List<TokenErro> errosLexicos = compilador.getErrosLexicos();
        if(errosLexicos == null || errosLexicos.isEmpty()) {
            errosStBuilder.append("Não há erros léxicos!\n");
        } else {
            for(TokenErro er : errosLexicos) {
                errosStBuilder.append("<" + er.getTokenClass().toString()+ ", '" + 
                                 er.getAtributo() + "', " +
                                 er.getDescricao()+ "> (linha "+er.getLinha()+")\n");
            }
            
            return errosStBuilder.toString();
        }
        
        //Erros Sintáticos
        List<ErroSintatico> errosSintaticos = compilador.getErrosSintaticos();

        if(errosSintaticos == null || errosSintaticos.isEmpty()) {
            errosStBuilder.append("Não há erros sintáticos!\n");
        } else {
            for(ErroSintatico er : errosSintaticos) {
                final List<Token> tokens = er.getTokens();

                String linha = "";
                if(tokens != null && ! tokens.isEmpty())
                    linha = " (linha " + tokens.get(0).getLinha() + ")\n";

                errosStBuilder.append(er.getDescricao() + linha);
            }
            
            return errosStBuilder.toString();
        }
        
        //Erros Semanticos
        List<ErroSemantico> errosSemanticos = compilador.getErrosSemanticos();

        if(errosSemanticos == null || errosSemanticos.isEmpty()) {
            errosStBuilder.append("Não há erros semânticos!");
        } else {
            for(ErroSemantico er : errosSemanticos) {
                String linha = " (linha " + er.getLinha() + ")\n";

                errosStBuilder.append(er.getDescricao() + linha);
            }
        }
        
        
        return errosStBuilder.toString();
    }
    
    /**
     * Pega a lista de tokens gerados
     * pelo analisador, sem alteracao.
     * 
     * @return um List<> com os Tokens
     */
    public List<Token> getListTokens(){
        return compilador.getTokens();
    }
    
    /**
     * Pega a lista de erros lexicos gerados
     * pelo analisador, sem alteracao.
     * 
     * @return um List<> com os Tokens
     */
    public List<TokenErro> getListErrosLexicos() {
        return compilador.getErrosLexicos();
    }

}
